package com.gopay.bis.service.bank.impl.expay;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import com.gopay.common.cipher.utils.LoggerMaskUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.w3c.dom.Document;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.dao.bankorder.BankContractInfoDAO;
import com.gopay.bis.dao.bankorder.impl.BankOrderDAOImpl;
import com.gopay.bis.manager.bank.BankOrderManager;
//import com.gopay.bis.manager.bank.BankOrderManager;
import com.gopay.bis.manager.bank.expay.IpayExPayManager;
import com.gopay.bis.service.bank.sms.SmsSupportController;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.CmbcConstants;
import com.gopay.common.constants.bank.IpayConstants;
import com.gopay.common.constants.bank.SpdbConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.ipay.expay.AuthenBindCard;
import com.gopay.common.domain.bank.ipay.expay.Head;
import com.gopay.common.domain.bank.ipay.expay.IpayExPayBaseMessage;
import com.gopay.common.domain.bank.ipay.expay.Query;
import com.gopay.common.domain.bis.BisBankContractInfo;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.MD5Util;
import com.gopay.remote.bank.ExPayInteractRemoteService;

/**
 * 民生i支付快捷接口
 * 
 * @IpayExPayServiceImpl.java
 * @author jiangxiangjiao
 */
public class IpayExPayServiceImpl implements ExPayInteractRemoteService {

	private static Logger logger = LoggerFactory.getLogger(IpayExPayServiceImpl.class);

	@Resource(name = "ipayExPayManager")
	private IpayExPayManager ipayExPayManager;

	@Resource(name = "bankContractInfoDAO")
	private BankContractInfoDAO bankContractInfoDAO;
	
	@Resource(name = "bankOrderDAO")
	BankOrderDAOImpl bankOrderDAO;
	
	@Resource(name = "bankOrderManager")
	private BankOrderManager bankOrderManager;
	
	
//	@Resource(name = "bankOrderManager")
//	private BankOrderManager bankOrderManager;

	// 短信验证码处理类
	public SmsSupportController smsController;

	/**
	 * 身份认证
	 */
	public Result certification(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
			// 查找该卡签约记录
			BisBankContractInfo contractInfo = findContractInfo(message);
			if (contractInfo == null) {
				logger.error("民生i支付快捷卡号：" + baseMsg.getCardNo() + "未签约");
				//签约绑卡
				result = authBindCard(message, false);
			}else if(StringUtils.equals("02", contractInfo.getContractState())){
				//2、有签约记录，但签约状态为失效(解约及支付失败时返回绑卡过期、无效绑卡ID、卡已解绑等信息时都会导致签约状态为失效),先解约在签约
				logger.error("民生i支付快捷卡号：" + baseMsg.getCardNo() + "签约已失效,先解约在重新签约");
				ipayExPayManager.UnBindCard(message,contractInfo.getContractNumber());
				result = authBindCard(baseMsg, true); // 重新签约
			}else{
				//3、签约记录有效
				String verifyCode = createVerificationCode(baseMsg); // 创建四要素校验码
				if (StringUtils.equals(verifyCode, contractInfo.getVerificationCode())) { // 比较四要素校验码是否匹配
					logger.info("民生i支付快捷卡号：" + message.getCardNo() + "已签约且四要素匹配,鉴权通过");
					result.setModel("flag", true);
					result.setSuccess(true);
					result.setModel("retMsg", "鉴权成功");
					result.setDefaultModel(contractInfo);
				} else {
					// 四要素信息不匹配，鉴权不通过,解约并重新签约
					logger.info("民生i支付快捷卡号:"+ LoggerMaskUtils.maskString(message.getCardNo()) +
							"已签约但签约信息不匹配,需解约,原签约信息" + LoggerMaskUtils.maskString(ToStringBuilder.reflectionToString(contractInfo)));
					IpayExPayBaseMessage unBind = (IpayExPayBaseMessage) ipayExPayManager.UnBindCard(message,
							contractInfo.getContractNumber());
					if (unBind != null && CmbcConstants.RESP_TYPE_SUCCESS.equals(unBind.getHead().getRespType())) {
						logger.info("民生i支付快捷卡号：" + message.getCardNo() + "解约成功");
						updateContractState(baseMsg, "02");
						result = authBindCard(baseMsg, true); // 重新签约
					}
				}
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E1147);
		}
		return result;
	}

	/**
	 * 发送短信验证码请求
	 */
	public Result sendSms(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
			Map<String, String> smsRes = smsController.sendSMS(message);
			if (ProcCodeConstants.PROC_CODE_100E6102.equals(smsRes.get("resCode"))) {
				// 短信发送成功
				result.setModel("flag", true);
			} else {
				// 短信发送失败
				result.setModel("flag", false);
			}
			result.setModel("sendCount", smsRes.get("sendCount"));
			result.setModel("retMsg", smsRes.get("retMsg"));
			result.setModel("resCode", smsRes.get("resCode"));
			result.setResultCode(smsRes.get("resCode"));
			result.setSuccess(true);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6077);
		}
		return result;
	}

	/**
	 * 验证短信请求
	 */
	public Result checkSms(ExPayBaseMessage baseMsg) {
		 Result result = new Result(false);
		 IpayExPayBaseMessage message = new IpayExPayBaseMessage();
	        BeanUtils.copyProperties(baseMsg, message);
	        try {
	            Map<String, String> smsRes = smsController.checkSMS(message);
	            if (ProcCodeConstants.PROC_CODE_100E6091.equals(smsRes.get("resCode"))) {
	                // 验证通过
	                result.setModel("flag", true);               
	            } else {
	                // 验证失败
	                result.setModel("flag", false);
	                if(!ProcCodeConstants.PROC_CODE_100E6099.equals(smsRes.get("resCode"))){
	                    Map<String, String> freezeRes = smsController.freezeCard(message);
	                    if(freezeRes != null)
	                        smsRes = freezeRes;
	                }
	            }
	            result.setModel("failCount", smsRes.get("failCount"));
	            result.setModel("retMsg", smsRes.get("retMsg"));
	            result.setModel("resCode", smsRes.get("resCode"));
	            result.setResultCode(smsRes.get("resCode"));
	            result.setSuccess(true);
	        } catch (Exception ex) {
	            BankLogUtils.printServiceImplExceptionLog(ex);
	            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6078);
	        }
	        return result;
	}

	/**
	 * 支付请求
	 */
	public Result payment(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		if(BisBankBusinessProd._05.value.equals(baseMsg.getBankBusProd().value)){
			baseMsg.setBankOrderId("IC" + TransUtil.processOrderIdTo14Digit(baseMsg.getOrderId()));
		}
		if(BisBankBusinessProd._15.value.equals(baseMsg.getBankBusProd().value)){
			baseMsg.setBankOrderId("ID" + TransUtil.processOrderIdTo14Digit(baseMsg.getOrderId()));
		}
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(baseMsg, message);
		
		try {
			BisBankContractInfo contractInfo = findContractInfo(message);
			message = (IpayExPayBaseMessage) ipayExPayManager.payment(message, contractInfo.getContractNumber());
			Head head = message.getHead();
			result.setDefaultModel(message.isVerifyFlag());
			result.setModel("res", message);
			
			Map<String, String> param = new HashMap<String, String>();

			logger.error("receive message:" + message.getPlainMessage());
			if (message.isVerifyFlag() && IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(head.getRespType())
					&& IpayConstants.EX_RESP_CODE_SUCCESS.equals(head.getRespCode())) {
				// 验签成功
				param.put("orderId", baseMsg.getOrderId());
				param.put("amt", baseMsg.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("isFront", String.valueOf(false));
				
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(true);
				
				//将银行返回的支付平台流水号记录到 	bis_bank_main_order	的	BANK_ORDER_ID	中
				DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
				XPath xpath = XPathFactory.newInstance().newXPath();
				InputStream inputStream = new ByteArrayInputStream(message.getPlainMessage().getBytes());
				Document document = builder.parse(inputStream);
				String payMsgId = (String)xpath.evaluate("message/body/payMsgId", document, XPathConstants.STRING);
				logger.error("支付平台返回订单流水号为：" + payMsgId);
				//result.setModel("bankOrderId", payMsgId);
				
				if (StringUtils.isNotEmpty(payMsgId)) {
	                // 如果是民生i支付，支付成功以后，将银行返回的支付平台流水号记录到 bis_bank_main_order 的
	                // BANK_ORDER_ID 中
	                //String bankReturnOrderId = result.getModel("bankOrderId").toString();
	                baseMsg.setBankReturnOrderId(payMsgId);
	                logger.error("pay success以后记录平台支付流水号：" + payMsgId);
	            }
				
			} else {
				logger.error("订单号：" + baseMsg.getOrderId() + "支付失败,错误码及错误信息：" + head.getRespCode()+":"+head.getRespMsg());
				if (IpayConstants.EX_RESP_CODE_ALREADY_UNBIND.equals(head.getRespCode())
						|| IpayConstants.EX_RESP_CODE_INVALID_BINDCARDID.equals(head.getRespCode())
						|| IpayConstants.EX_RESP_CODE_BINDCARD_EXPIRED.equals(head.getRespCode())) {
					updateContractState(baseMsg, "02"); // 更新卡的签约状态为已失效
				}
				
                if (IpayConstants.BANK_IPAY_DEAL_ERROR.equals(head.getRespType())) {
                    // 民生i支付明确分行失败add by zhengxue 20170313
                    result.setOrderFail(true);
                }
				// 通知后台地址该订单失败
				param.put("orderId", baseMsg.getOrderId());
				param.put("amt", baseMsg.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				// 记录数据库失败信息 add by zhengxue 20170313
                param.put("retMsg", StringUtils.isEmpty(head.getRespMsg()) ? "交易失败" : head.getRespMsg());
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(false);
				result.setBankRetCode(message.getBankRetCode());//add by liuyu, 20170802, 快捷API失败通知
			}
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6057);
		}
		return result;
	}

	/**
	 * 订单查询
	 */
	public Result queryOrder(ExPayBaseMessage base) {
		Result result = new Result(false);
		if(BisBankBusinessProd._05.value.equals(base.getBankBusProd().value)){
			base.setBankOrderId("IC" + TransUtil.processOrderIdTo14Digit(base.getOrderId()));
		}
		if(BisBankBusinessProd._15.value.equals(base.getBankBusProd().value)){
			base.setBankOrderId("ID" + TransUtil.processOrderIdTo14Digit(base.getOrderId()));
		}
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(base, message);
		try {
			message = (IpayExPayBaseMessage) ipayExPayManager.query(message);
			result.setDefaultModel(message);
			result.setSuccess(true);
			Map<String, String> param = new HashMap<String, String>();
			String amount = base.getAmount().toString();
			param.put("orderId", base.getOrderId());
			param.put("amount", amount);
			if (message == null || !IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(message.getHead().getRespType())) {
				// 查询结果为空
				param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
				param.put("returnMessage", "银行返回对账结果为空");
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				result.setModel("queryResult", param);
				return result;
			}
			if (message.isVerifyFlag()) {
				Query queryRes = (Query) message.getBody();
				if (IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(queryRes.getOriRespType())) {
					// 成功处理
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
					param.put("returnMessage", "交易成功");
					
					if(!base.getBankIntrChann().value.equals(BisBankBusinessProd._12.value)){
						updateBankOrder(base.getOutOrderId(), queryRes.getOriPayMsgId());
					}
					result.setOrderStatus(true);
					result.setModel("flag", true);
				} else if (IpayConstants.BANK_IPAY_DEAL_ERROR.equals(queryRes.getOriRespType())) {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
					param.put("returnMessage", "交易失败");
					
					result.setOrderStatus(false);
					result.setModel("flag", false);
					result.setBankRetCode(message.getBankRetCode());//add by liuyu, 20170803, 快捷API失败通知
				} else {
					//如果状态是原交易不存在，并且bis_bank_main_order订单表状态为00，就返回错误信息
					BankOrder bankOrder = bankOrderManager.getBankOrderById(base.getOutOrderId());
					if(IpayConstants.EX_RESP_CODE_NOT_EXIST.equals(queryRes.getOriRespCode())
							&& BankOrderStatus.PROCESS.equals(bankOrder.getOrderStatus())){
						throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
					}
					//如果状态是原交易不存在，并且bis_bank_main_order订单表状态为00，就返回错误信息
//					BankOrder bankOrder = bankOrderManager.getBankOrderById(base.getOutOrderId());
//					if(IpayConstants.EX_RESP_CODE_NOT_EXIST.equals(queryRes.getOriRespCode())
//							&& "00".equals(bankOrder.getOrderStatus())){
//						throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
//					}
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行订单正在处理中");
					result.setBankRetCode(message.getBankRetCode());//add by liuyu, 20170803, 快捷API失败通知
				}
			} else {
				param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				param.put("returnMessage", "银行验签失败");
				
				result.setOrderStatus(false);
				result.setModel("flag", false);
				result.setBankRetCode(message.getBankRetCode());//add by liuyu, 20170803, 快捷API失败通知
			}
			result.setModel("queryResult", param);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
			result.setOrderStatus(false);
			result.setModel("flag", false);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setOrderStatus(false);
			result.setModel("flag", false);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6058);
		}
		return result;
	}
	
	private void updateBankOrder(String outOrderId, String payMsgId){
		BankOrder bankOrder = new BankOrder();
		bankOrder.setOutOrderId(outOrderId);
		bankOrder.setBankOrderId(payMsgId);
		bankOrderDAO.update(bankOrder);
	}

	@Override
	public Result sign(ExPayBaseMessage baseMsg) {
		return null;
	}

	@Override
	public Result verify(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result treatyQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result cancel(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refund(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		baseMsg.setBankOrderId("TK" + TransUtil.processOrderIdTo14Digit(baseMsg.getOrderId()));
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
			message = (IpayExPayBaseMessage) ipayExPayManager.refund(message);

			if (message != null) {
				Head head = message.getHead();
				if (message.isVerifyFlag()) {
					if(IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(head.getRespType())
							&& IpayConstants.EX_RESP_CODE_SUCCESS.equals(head.getRespCode())){
						result.setDefaultModel(message);
						result.setOrderStatus(true);
						result.setSuccess(true);
						// 接收成功
						result.setModel("flag", true);
					}else{
						logger.error("订单号：" + baseMsg.getOrderId() + "退款失败,错误码及错误信息：" + head.getRespCode()+":"+head.getRespMsg());
						// 通知后台地址该订单失败
						result.setOrderStatus(false);
						result.setResultCode(ProcCodeConstants.PROC_CODE_100E6088);
						result.setErrorMsg(head.getRespMsg());
						result.setModel("flag", false);
						result.setSuccess(true);
					}
				} else {
					result.setSuccess(false);
					result.setModel("flag", false);
					result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
					result.setErrorMsg("验签失败");
				}
				logger.error("Received message body：" + ToStringBuilder.reflectionToString(message.getBody()));
			}else{
				result.setSuccess(false);
				result.setModel("flag", false);
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
			}
			
			result.setModel("retMsg", message.getHead().getRespMsg());
			
			
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		return result;
	}

/*	@Override
	public Result refundQuery(ExPayBaseMessage base) {
		Result result = new Result(false);
		if(BisBankBusinessProd._05.value.equals(base.getBankBusProd().value)){
			base.setBankOrderId("IC" + TransUtil.processOrderIdTo14Digit(base.getOrderId()));
		}
		if(BisBankBusinessProd._15.value.equals(base.getBankBusProd().value)){
			base.setBankOrderId("ID" + TransUtil.processOrderIdTo14Digit(base.getOrderId()));
		}
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(base, message);
		try {
			message = (IpayExPayBaseMessage) ipayExPayManager.query(message);
			result.setDefaultModel(message);
			result.setSuccess(true);
			Map<String, String> param = new HashMap<String, String>();
			String amount = base.getAmount().toString();
			param.put("orderId", base.getOrderId());
			param.put("amount", amount);
			if (message == null || !IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(message.getHead().getRespType())) {
				// 查询结果为空
				param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
				param.put("returnMessage", "银行返回对账结果为空");
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				result.setModel("queryResult", param);
				return result;
			}
			if (message.isVerifyFlag()) {
				Query queryRes = (Query) message.getBody();
				if (IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(queryRes.getOriRespType())) {
					// 成功处理
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
					param.put("returnMessage", "交易成功");
				} else if (IpayConstants.BANK_IPAY_DEAL_ERROR.equals(queryRes.getOriRespType())) {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
					param.put("returnMessage", "交易失败");
				} else {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行订单正在处理中");
				}
			} else {
				param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				param.put("returnMessage", "银行验签失败");
			}
			result.setModel("queryResult", param);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6058);
		}
		return result;
	}*/
	
	@Override
	public Result queryCvn(ExPayBaseMessage baseMsg) {
	    Result result = new Result();
        result.setSuccess(true);
        result.setModel("flag", true);
        result.setModel("isQueryCVN",SpdbConstants.SPDB_EXPAY_ISQUERYCVN);
        return result;
	}

	public SmsSupportController getSmsController() {
		return smsController;
	}

	public void setSmsController(SmsSupportController smsController) {
		this.smsController = smsController;
	}

	/**
	 * 鉴权绑卡（签约）,没有签约记录则新建签约信息，否则更新原签约信息
	 * 
	 * @param baseMsg
	 *            鉴权绑卡请求信息
	 * @param hasContract
	 *            是否已有签约记录
	 * @return Result
	 */
	public Result authBindCard(ExPayBaseMessage baseMsg, boolean hasContract) throws GopayException {
		Result result = new Result(false);
		result.setModel("flag", false);
		IpayExPayBaseMessage message = new IpayExPayBaseMessage();
		BeanUtils.copyProperties(baseMsg, message);
		IpayExPayBaseMessage bindCardRes = (IpayExPayBaseMessage) ipayExPayManager.certification(message);
		if (message != null && IpayConstants.BANK_IPAY_DEAL_SUCCESS.equals(bindCardRes.getHead().getRespType())) {
			result.setModel("retMsg", bindCardRes.getHead().getRespMsg());
			result.setDefaultModel((AuthenBindCard) bindCardRes.getBody());
			result.setModel("flag", true);
			result.setSuccess(true);
			AuthenBindCard bindCard = (AuthenBindCard) bindCardRes.getBody();
			if (!hasContract) {
				logger.info("民生i支付快捷卡号：" + baseMsg.getCardNo() + "签约成功,新建签约信息");
				newContract(message, bindCard.getBindId());
			} else {
				logger.info("民生i支付快捷卡号：" + baseMsg.getCardNo() + ",重新签约成功,更新签约信息");
				updateContractInfo(message, bindCard.getBindId(), "01");
			}
		}
		return result;
	}

	/**
	 * 根据卡号和签约银行查询生效签约记录
	 * 
	 * @param message
	 * @return
	 */
	public BisBankContractInfo findContractInfo(ExPayBaseMessage message) {
		BisBankContractInfo bisBankContractInfo = new BisBankContractInfo();
		bisBankContractInfo.setBankCode(message.getBank());
		bisBankContractInfo.setCardNo(message.getCardNo());
		bisBankContractInfo.setBankBizProdCode(message.getBankBusProd().value);
		bisBankContractInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
		return bankContractInfoDAO.getContractInfoByCard(bisBankContractInfo);
	}

	/**
	 * 根据绑卡ID修改鉴权绑卡生效状态
	 * 
	 * @param message
	 * @param bindCardId
	 *            绑卡ID
	 * @param state
	 *            签约状态
	 * @return
	 */
	public void updateContractInfo(ExPayBaseMessage message, String bindCardId, String constractState) {
		BisBankContractInfo bisBankContractInfo = new BisBankContractInfo();
		bisBankContractInfo.setContractState(constractState);
		bisBankContractInfo.setCardNo(message.getCardNo());
		bisBankContractInfo.setContractNumber(bindCardId);
		bisBankContractInfo.setBindMobile(message.getMediaId());
		bisBankContractInfo.setBankCode(message.getBank());
		String verifyCode = createVerificationCode(message);
		// 保存四要素校验码
		bisBankContractInfo.setVerificationCode(verifyCode);
		bankContractInfoDAO.updateContractInfo(bisBankContractInfo);
	}

	/**
	 * 根据绑卡ID修改鉴权绑卡生效状态
	 * 
	 * @param message
	 * @param bindCardId
	 *            绑卡ID
	 * @param state
	 *            签约状态
	 * @return
	 */
	public void updateContractState(ExPayBaseMessage message, String constractState) {
		BisBankContractInfo bisBankContractInfo = new BisBankContractInfo();
		bisBankContractInfo.setContractState(constractState);
		bisBankContractInfo.setCardNo(message.getCardNo());
		bisBankContractInfo.setBankCode(message.getBank());
		bisBankContractInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
		bisBankContractInfo.setBankBizProdCode(message.getBankBusProd().value);
		bankContractInfoDAO.updateContractState(bisBankContractInfo);
	}

	/**
	 * 新建鉴权绑卡信息
	 * 
	 * @param message
	 * @param bindCardId
	 *            银行返回绑卡ID
	 * @return
	 */
	public void newContract(ExPayBaseMessage message, String bindCardId) {
		BisBankContractInfo bisBankContractInfo = new BisBankContractInfo();
		bisBankContractInfo.setBankCode(message.getBank());
		bisBankContractInfo.setBankBizProdCode(message.getBankBusProd().value);
		bisBankContractInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
		bisBankContractInfo.setCardNo(message.getCardNo());
		bisBankContractInfo.setContractState("01");
		bisBankContractInfo.setContractNumber(bindCardId);
		bisBankContractInfo.setBindMobile(message.getMediaId());
		bisBankContractInfo.setUeserId(message.getIdentityCode());
		String verifyCode = createVerificationCode(message);
		// 保存四要素校验码
		bisBankContractInfo.setVerificationCode(verifyCode);
		bisBankContractInfo.setContractNumber(bindCardId);
		bankContractInfoDAO.insertBisBankContractInfo(bisBankContractInfo);
	}

	/**
	 * 根据用户输入的四要素/六要素创建校验码
	 * 
	 * @param message
	 * @return
	 */
	public String createVerificationCode(ExPayBaseMessage message) {
		StringBuffer msg = new StringBuffer();
		// 信用卡 增加CVN2和有效期两要素
		if(BisBankBusinessProd._05.value.equals(message.getBankBusProd().value)){
			msg.append(message.getCvv2());
			msg.append(message.getAvailableDate());
		}
		msg.append(message.getCardHolder());
		msg.append(message.getCardNo());
		msg.append(message.getIdentityCode());
		msg.append(message.getMediaId());
		return MD5Util.sign(msg.toString());
	}
	

    @Override
    public Result queryNeedCert(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result refundBack(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

}
